#pragma once
#include "Items.h"
#include "../Engine/Engine.h"
#include "../Engine/Networking/templateVectorList.h"
#include "../Engine/Networking/templatevector.h"
#include <fstream>

#define addAsset  Engine::Ins()->graphics.AddAsset
#define addToDraw Engine::Ins()->dlHandler.AddObject
#define vItemBase	Vector<Item_Base*>	 
#define vProjectile TemplateVectorList<Item_Projectile>*

class Factory
{
public:
	enum ASSET
	{
		alpha,
		collider,
		//Projectiles
		fireBall,
		//EQUIPMENT		
		bowieKnife,	//Keep this in first for equippables
		energyMace,
		handGun,
		ehandGun,
		magRifle,
		ironCuirass,
		ironHand,
		ironArm,
		ironFoot,
		ironThigh,
		ironHelm,
		mharysCuirass,
		mharysHand,
		mharysArm,
		mharysFoot,
		mharysThigh,
		mharysHelm,
		carbitaniumCuirass,
		carbitaniumHand,
		carbitaniumArm,
		carbitaniumFoot,
		carbitaniumThigh,
		carbitaniumHelm,
		//Consumable
		medOsazine,		//Keep This in first for consumables
		medMetazine,	//Super-Osazine
		medAdrenelol,
		//Materials
		mInoriteBar,
		mInoriteIngot,
		mInoriteWafer,
		mInoriteBillet,
		mTurfPaste,
		mFoamGel,
		mNanoGel,
		mResin,
		mEnergySalve,
		mAlgaeCluster,
		mEarthFlesh,
		mMetalPlate,
		mConductor,
		mEnergyNode,
		ITEM_SIZE
	};

private:

	static const int PROJECTILE_POOL_SIZE = 50;
	TemplateVectorList<Item_Projectile> projectilePool;

	Factory():projectilePool(PROJECTILE_POOL_SIZE){};
	Item_Base* create(int const & a_type);

	void initOriginalCopies();
	Item_Equippable* initEquippable(char* fileName, int item);
	Item_Consumable* initConsumable(char* fileName,int item);
	Item_Equippable* initMaterial(char* fileName,int item);

	Vector2D	m_artAssets[ITEM_SIZE];	
	Vector2D	m_iconAssets[ITEM_SIZE];	//The icon to show in the inventory, hotbar and craft menu
	recipe		recipeBook[ITEM_SIZE];		//Holds the recipes for each of the objects;
	Item_Base*	m_originalCopy[ITEM_SIZE];	//Holds the original copy of each item that every other item is copied from.

public:

	//=====ACCESSORS
	static Factory& get(){static Factory f;return f;}
	inline vProjectile GetProjectileList() {return &projectilePool;}
	void getOriginalCopies(Item_Base* Items[])
	{
		for(int i = 0;  i < ITEM_SIZE; i++)
			Items[i] = m_originalCopy[i];
	};
	Item_Base* getItemAtIndex(int index)
	{
		return m_originalCopy[index];
	}
	char* getRecipe(int assetVal, int ingredVal)
	{
		return recipeBook[assetVal].namIngredients[ingredVal];
	}

	//=====MUTATORS
	void uncreate(Item_Base * e, int a_type);

	Item_Base*		 makeItem(ASSET item, int Type);
	Item_Equippable* makeEquippable(int item);
	Item_Consumable* makeConsumable(int item);
	Item_Equippable* makeMaterial(int item);
	Item_Projectile* buildProjectile(Vector3D pos, float Dir, float Mag, bool Physics, bool Movement, short Range, short Alignment, Vector3D PIE, ASSET item);

	void makeCollider(Vector3D pos, float lastXDir, float magnitude, bool Physics, bool Movement, short Range,
		short Alignment, Vector3D PIE, short colliderType, char* name);
	void addMultiplayerProjectile(Item_Projectile*);

	//=====CRAFTING
	int			getAssetEnum(Item_Base* toCheck);				//Takes an item and returns its index from the ASSETS enum
	void		craftObject(vItemBase &Inventory, int ItemID);	//Crafts a specified object, removing the required things from inventory.
	vItemBase	createRecipeBook(vItemBase Inventory);			//Looks at the inventory, compares it to all recipes, decides what's viable

	//=====STANDARD FUNCTIONS
	void initAssets();
	void update();
	void Release();

};